<template>
  <div class="login-container">
    <el-card class="login-card">
      <div class="card-header">
        <h2>登录</h2>
      </div>
      <el-form :model="loginForm" :rules="rules" ref="loginFormRef" label-position="left" label-width="80px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="loginForm.password" type="password" placeholder="请输入密码" show-password></el-input>
        </el-form-item>

        <el-form-item label="验证码" prop="captcha">
          <div style="display: flex; align-items: center;">
            <el-input v-model="loginForm.captcha" placeholder="请输入验证码"
              style="width: 200px; margin-right: 10px;"></el-input>
            <canvas ref="verifyCanvas" @click="refreshVerifyCode" class="verify-code-canvas"></canvas>
          </div>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="submitForm" :loading="loading" class="submit-btn">登录</el-button>
        </el-form-item>

        <div class="register-link">
          还没有账号？<router-link to="/register">立即注册</router-link>
        </div>
      </el-form>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import apiClient from '@/api/api'
import store from '@/store'

const router = useRouter()
const loginFormRef = ref(null)
const loading = ref(false)

const loginForm = reactive({
  username: '',
  password: '',
  captcha: ''
})

// 验证码相关
const verifyCanvas = ref<HTMLCanvasElement | null>(null)
const verifyCode = ref('')

// 生成随机验证码
const generateVerifyCode = () => {
  const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let code = ''
  for (let i = 0; i < 4; i++) {
    code += chars[Math.floor(Math.random() * chars.length)]
  }
  verifyCode.value = code
  return code
}

// 绘制验证码
const drawVerifyCode = () => {
  const canvas = verifyCanvas.value
  if (!canvas) return

  const ctx = canvas.getContext('2d')
  if (!ctx) return

  // 设置画布大小
  canvas.width = 100
  canvas.height = 40

  // 填充背景
  ctx.fillStyle = '#f0f0f0'
  ctx.fillRect(0, 0, canvas.width, canvas.height)

  // 生成新验证码
  const code = generateVerifyCode()

  // 绘制文字
  ctx.font = 'bold 24px Arial'
  ctx.textBaseline = 'middle'
  for (let i = 0; i < code.length; i++) {
    ctx.fillStyle = `rgb(${Math.random() * 100}, ${Math.random() * 100}, ${Math.random() * 100})`
    ctx.fillText(code[i], 20 + i * 20, canvas.height / 2)
  }

  // 绘制干扰线
  for (let i = 0; i < 4; i++) {
    ctx.strokeStyle = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`
    ctx.beginPath()
    ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height)
    ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height)
    ctx.stroke()
  }
}

// 刷新验证码
const refreshVerifyCode = () => {
  drawVerifyCode()
}

// 组件挂载时初始化验证码
onMounted(() => {
  document.title = '登录'
  drawVerifyCode()
})

// 表单验证规则
const rules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, message: '密码长度至少为 6 个字符', trigger: 'blur' }
  ],
  captcha: [
    { required: true, message: '请输入验证码', trigger: 'blur' },
    { min: 4, max: 4, message: '验证码长度必须为4位', trigger: 'blur' }
  ]
}

const submitForm = () => {
  if (loginForm.captcha.toLowerCase() !== verifyCode.value.toLowerCase()) {
    ElMessage({
      type: 'error',
      message: '验证码错误'
    })
    refreshVerifyCode()
    return
  }

  if (!loginFormRef.value) return
  (loginFormRef.value as any).validate(async (valid: boolean) => {
    if (valid) {
      loading.value = true
      await apiClient.post('/user/login', {
        username: loginForm.username,
        password: loginForm.password
      }).then(response => {
        const data = response.data
        if (data.code !== 1) {
          ElMessage({
            type: 'error',
            message: data.message
          })
          refreshVerifyCode()
        } else {
          ElMessage({
            type: 'success',
            message: "登录成功"
          })
          // 将用户信息保存到 Vuex 中
          store.commit('setUserId', data.data.id)
          store.commit('setUserIdentity', data.data.role)
          store.commit('setUserAvatar', data.data.avatar)
          
          // 将用户信息保存到本地存储中
          localStorage.setItem('token', data.data.token)
          localStorage.setItem('userId', data.data.id)
          localStorage.setItem('userRole', data.data.role)
          localStorage.setItem('userAvatar', data.data.avatar)
          // 登录成功后的处理
          /*if(data.data.role === 1){
            router.push('/admin') 
          }else if(data.data.role === 3){
            router.push('/landlord')
          }else{
            router.push('/')
          }*/
          router.push('/')
        }
      }).catch(error => {
        ElMessage({
          type: 'error',
          message: error.response.data.message || '登录失败，请稍后再试'
        })
        refreshVerifyCode()
      })
      loading.value = false
    } else {
      ElMessage({
        type: 'warning',
        message: '请正确填写所有必填项'
      })
      return false
    }
  })
}
</script>

<style scoped>
.login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 90vh;
}

.login-card {
  width: 100%;
  max-width: 500px;
}

.card-header {
  display: flex;
  justify-content: center;
  margin-bottom: 30px;
}

.el-form-item {
  margin-bottom: 25px;
}

:deep(.el-input__wrapper) {
  height: 45px;
}

:deep(.el-button) {
  height: 45px;
  font-size: 16px;
}

.submit-btn {
  width: 100%;
}

.register-link {
  text-align: center;
  margin-top: 20px;
  font-size: 14px;
}

.register-link a {
  color: #409eff;
  text-decoration: none;
}

.register-link a:hover {
  text-decoration: underline;
}
</style>
